#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
主题:映射名称到序列元素
问题: 你有一段通过下标访问列表或者元组中元素的代码，但是这样有时候会使得你的代码难以阅读， 于是你想通过名称来访问元素。
提示 : 
"""

from collections import namedtuple

Stock = namedtuple('Stock', ['name', 'shares', 'price'])
Subscriber = namedtuple('Subscriber', ['addr', 'joned'])


def recipe1():
    """collections.namedtuple() 函数"""
    sub = Subscriber('jonesy@example.com', '2012-10-19')
    print(f"{sub = }")
    print(f"{sub.addr = }")
    print(f"{sub.joned = }")

    # 尽管 namedtuple 的实例看起来像一个普通的类实例，但是它跟元组类型是可交换的，支持所有的普通元组操作，比如索引和解压
    print(f"{len(sub) = }")
    addr, joined = sub
    print(f"{addr = }")
    print(f"{joined = }")


def recipe2():
    """命名元组另一个用途就是作为字典的替代，因为字典存储需要更多的内存空间"""
    s = Stock('ACME', 100, 123.45)
    print(f"{s = }")

    s = s._replace(shares=75)  # 更新
    print(f"{s = }")

def recipe3():
    """_replace() 方法还有一个很有用的特性就是当你的命名元组拥有可选或者缺失字段时候， 它是一个非常方便的填充数据的方法"""
    s = Stock(None, 0, 0)
    a = {'name': 'ACME', 'shares': 100}
    print(f"{s._replace(**a) = }")
    

def main():
    print('recipe1'.center(20, '*'))
    recipe1()
    print('recipe2'.center(20, '*'))
    recipe2()
    print('recipe3'.center(20, '*'))
    recipe3()

if __name__ == '__main__':
    main()
